package cn.wetcland.es.utils;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.wetcland.es.config.exception.CustomerException;
import cn.wetcland.es.config.exception.CustomerExceptionTypeEnum;

import javax.servlet.http.HttpSession;
import java.util.Map;

/**
 * 自定义断言器
 */
public class MyAssert {

    public static void verifyAlreadyLogin(HttpSession session) {
        MyAssert.notNull(session.getAttribute("target"), "请先登录");
    }

    public static void verifyRoleTeacher(HttpSession session) {
        verifyAlreadyLogin(session);
        if (session.getAttribute("roleName") != "teacher") {
            throw new CustomerException(CustomerExceptionTypeEnum.ASSERT_WARNING, "当前登录角色权限不足");
        }
    }

    public static void verifyRoleStudent(HttpSession session) {
        verifyAlreadyLogin(session);
        if (session.getAttribute("roleName") != "student") {
            throw new CustomerException(CustomerExceptionTypeEnum.ASSERT_WARNING, "当前登录角色不为学生");
        }
    }

    public static void isTrue(boolean expression, String msg) {
        if (!expression) {
            throw new CustomerException(CustomerExceptionTypeEnum.ASSERT_WARNING, msg);
        }
    }

    public static void isFalse(boolean expression, String msg) {
        if (expression) {
            throw new CustomerException(CustomerExceptionTypeEnum.ASSERT_WARNING, msg);
        }
    }

    public static void isNull(Object object, String msg) {
        if (null != object) {
            throw new CustomerException(CustomerExceptionTypeEnum.ASSERT_WARNING, msg);
        }
    }

    public static <T> T notNull(T object, String msg) {
        if (null == object) {
            throw new CustomerException(CustomerExceptionTypeEnum.ASSERT_WARNING, msg);
        } else {
            return object;
        }
    }

    public static <T extends CharSequence> T notEmpty(T text, String msg) {
        if (StrUtil.isEmpty(text)) {
            throw new CustomerException(CustomerExceptionTypeEnum.ASSERT_WARNING, msg);
        } else {
            return text;
        }
    }

    public static <T extends CharSequence> T notBlank(T text, String msg) {
        if (StrUtil.isBlank(text)) {
            throw new CustomerException(CustomerExceptionTypeEnum.ASSERT_WARNING, msg);
        } else {
            return text;
        }
    }

    public static <T extends CharSequence> T notContain(CharSequence textToSearch, T substring, String msg) {
        if (StrUtil.contains(textToSearch, substring)) {
            throw new CustomerException(CustomerExceptionTypeEnum.ASSERT_WARNING, msg);
        } else {
            return substring;
        }
    }

    public static <T> T[] notEmpty(T[] array, String msg) {
        if (ArrayUtil.isEmpty(array)) {
            throw new CustomerException(CustomerExceptionTypeEnum.ASSERT_WARNING, msg);
        } else {
            return array;
        }
    }

    public static <T> T[] noNullElements(T[] array, String msg) {
        if (ArrayUtil.hasNull(array)) {
            throw new CustomerException(CustomerExceptionTypeEnum.ASSERT_WARNING, msg);
        } else {
            return array;
        }
    }

    public static <E, T extends Iterable<E>> T notEmpty(T collection, String msg) {
        if (CollUtil.isEmpty(collection)) {
            throw new CustomerException(CustomerExceptionTypeEnum.ASSERT_WARNING, msg);
        } else {
            return collection;
        }
    }

    public static <K, V, T extends Map<K, V>> T notEmpty(T map, String msg) {
        if (MapUtil.isEmpty(map)) {
            throw new CustomerException(CustomerExceptionTypeEnum.ASSERT_WARNING, msg);
        } else {
            return map;
        }
    }

    public static <T> T isInstanceOf(Class<?> type, T obj, String msg) {
        notNull(type, "断言实例必须不为NULL");
        if (!type.isInstance(obj)) {
            throw new CustomerException(CustomerExceptionTypeEnum.ASSERT_WARNING, msg);
        } else {
            return obj;
        }
    }

    public static void state(boolean expression, String msg) {
        if (!expression) {
            throw new CustomerException(CustomerExceptionTypeEnum.ASSERT_WARNING, msg);
        }
    }

    public static int checkIndex(int index, int size, String msg) {
        if (index >= 0 && index < size) {
            return index;
        } else {
            throw new CustomerException(CustomerExceptionTypeEnum.ASSERT_WARNING, msg);
        }
    }

    public static int checkBetween(int value, int min, int max, String msg) {
        if (value >= min && value <= max) {
            return value;
        } else {
            throw new CustomerException(CustomerExceptionTypeEnum.ASSERT_WARNING, msg);
        }
    }

    public static Number checkBetween(Number value, Number min, Number max, String msg) {
        notNull(value, "value值必须不为NULL");
        notNull(min, "min值必须不为NULL");
        notNull(max, "max值必须不为NULL");
        double valueDouble = value.doubleValue();
        double minDouble = min.doubleValue();
        double maxDouble = max.doubleValue();
        if (!(valueDouble < minDouble) && !(valueDouble > maxDouble)) {
            return value;
        } else {
            throw new CustomerException(CustomerExceptionTypeEnum.ASSERT_WARNING, msg);
        }
    }

    public static void notEquals(Object obj1, Object obj2, String msg) {
        if (ObjectUtil.equals(obj1, obj2)) {
            throw new CustomerException(CustomerExceptionTypeEnum.ASSERT_WARNING, msg);
        }
    }

    public static void equals(Object obj1, Object obj2, String msg) {
        if (ObjectUtil.notEqual(obj1, obj2)) {
            throw new CustomerException(CustomerExceptionTypeEnum.ASSERT_WARNING, msg);
        }
    }

}
